use ndarray::Array2;
use std::error::Error;

use crate::board::Player;

/// 解析棋盘状态字符串
/// 格式: "B,W,.;.,B,.;W,.,B" 表示3x3棋盘
pub fn parse_board_state(
    s: &str,
    rows: usize,
    cols: usize,
) -> Result<Array2<Option<Player>>, Box<dyn Error>> {
    let mut board = <Array2<Option<Player>>>::from(Array2::from_elem((rows, cols), None));

    let rows_str: Vec<&str> = s.split(';').collect();
    if rows_str.len() != rows {
        return Err(format!(
            "状态字符串行数错误，应为{}行，实际{}行",
            rows,
            rows_str.len()
        )
        .into());
    }

    for (i, row_str) in rows_str.iter().enumerate() {
        let cells: Vec<&str> = row_str.split(',').collect();
        if cells.len() != cols {
            return Err(format!("第{}行列数错误，应为{}列，实际{}列", i, cols, cells.len()).into());
        }

        for (j, cell) in cells.iter().enumerate() {
            board[(i, j)] = match *cell {
                "B" => Some(Player::Black),
                "W" => Some(Player::White),
                "." | "" => None,
                _ => return Err(format!("无效棋子标识: '{}'", cell).into()),
            };
        }
    }

    Ok(board)
}
